<!DOCTYPE html><html><head><title>Angular todomvc项目</title><meta charset='utf-8'><link href='https://dn-maxiang.qbox.me/res-min/themes/marxico.css' rel='stylesheet'><style>
.note-content  {font-family: 'Helvetica Neue', Arial, 'Hiragino Sans GB', STHeiti, 'Microsoft YaHei', 'WenQuanYi Micro Hei', SimSun, Song, sans-serif;}

</style></head><body><div id='preview-contents' class='note-content'>
                        
                    



<h2 id="angular-todomvc项目">Angular todomvc项目</h2>



<h3 id="需求分析">需求分析</h3>

<ol><li rel="1">功能分析： <br>
<ol>
<li rel="1">把数据库中内容展示到页面中</li>
<li rel="2">可以添加新的任务</li>
<li rel="3">可以对任务进行删除操作</li>
<li rel="4">双击显示区域时可以对已经添加的任务进行修改</li>
<li rel="5">任务有completed 和 active 两种样式</li>
<li rel="6">可以批量设置任务的状态</li>
<li rel="7">显示active的任务数</li>
<li rel="8">可以一键删除所有的已经完成项目</li>
<li rel="9">可以切换显示的状态  all || completed || active</li></ol></li>
<li rel="2">数据分析： <br>
<ol>
<li rel="1">每一个有对应的 id</li>
<li rel="2">有自己的对应的 name</li>
<li rel="3">显示自己的状态 completed </li></ol></li>
<li rel="3">在进行每一个js块代码时，应使用沙箱模式进行 ，把angular传参进入页面</li>
</ol>



<pre class="prettyprint with-line-number hljs-light"><code class="language-javascript hljs"><span class="hljs-comment line-number">1.</span>(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">angular</span>)</span>{<br><span class="hljs-comment line-number">2.</span>    <span class="hljs-comment">//防止对angular进行变量污染</span><br><span class="hljs-comment line-number">3.</span><br><span class="hljs-comment line-number">4.</span>})(angular);<br></code></pre>



<h3 id="功能分析">功能分析</h3>

<ol><li rel="1">根据数据库数据把todos展示到页面中</li>
<li rel="2">可以添加新的任务</li>
<li rel="3">可以对已经添加的任务进行删除操作</li>
<li rel="4">可以对已经添加的任务进行编辑</li>
<li rel="5">有对应的active样式和completed样式</li>
<li rel="6">可以批量设置任务的完成状态</li>
<li rel="7">实时显示active的任务数目</li>
<li rel="8">可以清除已经完成的任务数目</li>
<li rel="9">可以切换all   active   和 completed</li>
</ol>



<h3 id="任务进程">任务进程</h3>



<h4 id="功能0基础设置">功能0：基础设置</h4>

<ol><li rel="1">建立html页面，引入angular库</li>
<li rel="2">建立主模块，主控制器；服务模块、服务控制器；  在主模块中添加服务模块</li>
</ol>



<h4 id="功能1展示数据">功能1：展示数据</h4>

<ol><li rel="1">在module层得到数据库数据，建立闭包数据来进行页面的数据缓存，（和view层进行数据的双向绑定），并把得到数据方法传给controller层</li>
<li rel="2">controller层进行把数据存储在域中，在view层中利用ng-repeat进行渲染；</li>
</ol>



<h4 id="功能2添加新数据">功能2：添加新数据</h4>

<ol><li rel="1">在view层的input中建立数据双向绑定，controller层可以得到数据</li>
<li rel="2">在view层建立提交事件 form ng-submit  执行add事件</li>
<li rel="3">controller层中add事件  先判定view层双向绑定的数据是否有值  /\S+/.test  再把$scope.newTodo传参给module层 ，再把双向绑定的 newTodo清空</li>
<li rel="4">module层中add事件  把得到的newTodo添加到闭包数据中，并把闭包数据和数据库进行保存  ( 封装一个this.save() 方法 ); <br>
<strong>// 因为在服务模块中的闭包数据改变，带动主控制器中的$scope.todos改变  从而数据双向绑定，让view层动态渲染</strong></li>
</ol>



<h4 id="功能3-可以进行数据的删除">功能3： 可以进行数据的删除</h4>

<ol><li rel="1">view层对应的删除按钮设置 ng-click 事件  执行remove事件  把对应的 v.id传递给controller层；</li>
<li rel="2">controller层中把对应的id传递给module层  （方法传参）；</li>
<li rel="3">module层中遍历闭包数据，把对应id的项目删除 todos[i].splice( i,1 )  ，并保存到数据库中；</li>
</ol>



<h4 id="功能4内容在双击时可以进行编辑">功能4：内容在双击时可以进行编辑</h4>

<ol><li rel="1">view层在展示部分建立ng-dblclick事件：把对应的v.id传递给controller层；</li>
<li rel="2">controller层根据传来的id，设置正在编辑id $scope.isEditingId为对应的id；</li>
<li rel="3">在view层中，通过ng-class=”{ editing: v.id===isEditingId }   切换li的 editing类名来控制 input和展示页的显示与否（也可通过ng-show） <br>
<strong>//  通过设置页面的ng-show和ng-hide相同逻辑来给相互切换的的结构进行显示与否</strong></li>
<li rel="4">给view层的input和显示内容设置双向绑定 可以在事件和事件结束时相互显示相同；添加ng-submit事件 和ng-blur事件执行保存 </li>
<li rel="5">因为在view层中的数据改变直接可以影响到module层 所以直接在controller层中用方法调用module层中的save方法同步更新给数据库   $myServ.save();  isEditingId = -1;</li>
</ol>



<h5 id="功能4-ux增强-使用自定义指令-让在双击时自动进行获取焦点">功能4 UX增强 ：使用自定义指令  让在双击时自动进行获取焦点</h5>



<pre class="prettyprint with-line-number hljs-light"><code class="language-javascript hljs"><span class="hljs-comment line-number">1.</span>app.directive(<span class="hljs-string">'autoFocus'</span>,[<span class="hljs-string">'$timeout'</span><span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">$timeout</span>)</span>{<br><span class="hljs-comment line-number">2.</span>    <span class="hljs-keyword">return</span> {<br><span class="hljs-comment line-number">3.</span>        restrict: <span class="hljs-string">'A'</span>,     <span class="hljs-comment">// 只在属性中使用</span><br><span class="hljs-comment line-number">4.</span>        scope:{<br><span class="hljs-comment line-number">5.</span>            focus:<span class="hljs-string">'@'</span>      <span class="hljs-comment">//使用'@' 使focus的属性值在scope上</span><br><span class="hljs-comment line-number">6.</span>        },<br><span class="hljs-comment line-number">7.</span>        link: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">scope,element,attrs</span>)</span>{<br><span class="hljs-comment line-number">8.</span>            scope.$watch（<span class="hljs-string">'focus'</span>,<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">now</span>)</span>{<span class="hljs-comment">//对focus监听</span><br><span class="hljs-comment line-number">9.</span>                <span class="hljs-keyword">if</span>(now){     <span class="hljs-comment">//如果现在为true</span><br><span class="hljs-comment line-number">10.</span>                    <span class="hljs-comment">//用timeout在页面设置好后再让其得到焦点</span><br><span class="hljs-comment line-number">11.</span>                    $timeout(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{<br><span class="hljs-comment line-number">12.</span>                        element[<span class="hljs-number">0</span>].focus();<span class="hljs-comment">//对应input得到焦点</span><br><span class="hljs-comment line-number">13.</span>                    })<br><span class="hljs-comment line-number">14.</span>                }<br><span class="hljs-comment line-number">15.</span>            }）<br><span class="hljs-comment line-number">16.</span>        }<br><span class="hljs-comment line-number">17.</span>    };<br><span class="hljs-comment line-number">18.</span>}]);<br></code></pre>



<h4 id="功能5每一项使用对应的样式">功能5：每一项使用对应的样式</h4>

<p>1.view层中样式使用ng-class 使用数据的completed来控制样式 <br>
2.在view层中对checkbox进行数据双向绑定  与v.completed 实时设置对应数据的completed属性值 ，同时可以对样式进行改变 <br>
3.对checkbox进行ng-change事件，ng-change事件时调用$myServ.save()方法与数据库进行同步；</p>



<h4 id="功能6批量设置状态">功能6：批量设置状态</h4>

<ol><li rel="1">view层对批量设置checkbox进行数据双向绑定 ng-model=”selectAll” 把状态传递给controller层</li>
<li rel="2">view层对checkbox进行ng-change事件绑定，all（） </li>
<li rel="3">controller层中执行all事件把对应的$scope.selectAll状态传递给module层</li>
<li rel="4">module层中的all事件 接收到all的状态，遍历闭包数据，把状态设置为和all状态相同</li>
<li rel="5">因为todos和view层中数据绑定，所以实时渲染到页面中，进行this.save() 更新到数据库中</li>
</ol>



<h4 id="功能7记录active的数量">功能7：记录active的数量</h4>

<ol><li rel="1">在module层中把遍历闭包数据，把对应的completed=false的项计数，使用方法传递给controller层 </li>
<li rel="2">在controller层中用域方法把module层的方法的返回值传递给view层</li>
<li rel="3">在view层中  用  {{ getActive() }} 来把module层中的方法返回值放在页面</li>
<li rel="4">如果view层中的数据有变化，会影响到module层中的闭包数据，闭包数据动态改变getActive的方法返回值，从而可以对页面进行动态渲染</li>
</ol>



<h4 id="功能8可以对completed项目进行批量删除">功能8：可以对completed项目进行批量删除</h4>

<ol><li rel="1">在view层注册ng-click事件   clear（）</li>
<li rel="2">在controller层中调用module层中clear方法对闭包数据进行处理</li>
<li rel="3">module层中clear方法  遍历闭包数据  对completed=true的项目删除 todos.splite( i–,1 )    <strong>// 注意在数组中进行项目删除时 下一项会变为当前项，应进行i–操作</strong> </li>
<li rel="4">module层操作后进行数据库同步   </li>
</ol>



<h4 id="功能9根据不同的点击进行不同的显示">功能9：根据不同的点击进行不同的显示</h4>

<ol><li rel="1">因为在页面中有闭包数据 ，所以不需要进行数据的请求  ，直接使用filter对数据进行过滤渲染即可；</li>
<li rel="2">view层中ng-repeat=” v in todos | filter : Filter ”    //设置参数在controller层中修改</li>
<li rel="3">controler层中 用 <span>$</span>scope.loca = <span class="" rel="f450352385a88d2df479bc48c8a6a96f"><span class="MathJax_SVG" id="MathJax-Element-1-Frame" role="textbox" aria-readonly="true" style="font-size: 100%; display: inline-block;"><span><img type="image/png" width="100" height="22" longdesc="__SVG__undefined" src="" style="margin-top:0;margin-bottom:0;"></span></span></span>location 设置在域上来使用<span>$</span>watch监听锚点值    $scope.Filter = {};  //空过滤器  </li>
<li rel="4">监听页面的锚点值  对过滤器进行设置</li>
</ol>



<pre class="prettyprint with-line-number hljs-light"><code class="language-javascript hljs"><span class="hljs-comment line-number">1.</span>    $scope.$watch(<span class="hljs-string">'loca.hash()'</span>,<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">now</span>)</span>{        <br><span class="hljs-comment line-number">2.</span>        <span class="hljs-keyword">switch</span>(now){<br><span class="hljs-comment line-number">3.</span>            <span class="hljs-keyword">case</span> <span class="hljs-string">'/'</span>:<br><span class="hljs-comment line-number">4.</span>                $scope.Filter.completed = undefind;<br><span class="hljs-comment line-number">5.</span>                <span class="hljs-keyword">break</span>;      <br><span class="hljs-comment line-number">6.</span>            <span class="hljs-keyword">case</span> <span class="hljs-string">'/active'</span>:<br><span class="hljs-comment line-number">7.</span>                $scope.Filter.completed = <span class="hljs-literal">false</span>;<br><span class="hljs-comment line-number">8.</span>                <span class="hljs-keyword">break</span>;<br><span class="hljs-comment line-number">9.</span>            <span class="hljs-keyword">case</span> <span class="hljs-string">'/completed'</span>:<br><span class="hljs-comment line-number">10.</span>                $scope.Filter.completed = <span class="hljs-literal">true</span>;<br><span class="hljs-comment line-number">11.</span>                <span class="hljs-keyword">break</span>;<br><span class="hljs-comment line-number">12.</span>        }<br><span class="hljs-comment line-number">13.</span>    });<br></code></pre>

<ol start="5"><li rel="5">view层中样式切换  ng-class=” { selected : Filter.completed === undefind } ” //all <br>
ng-class=”{ selected : Filter.completed === false }”   //active <br>
ng-class=” { selected : Filter.completed === true } ”  //completed</li>
</ol></div></body></html>